package be.ipl.abeille.testNG;

import java.util.GregorianCalendar;

import org.testng.Assert;
import org.testng.annotations.Test;

import be.ipl.abeille.domaine.Const.Difficulte;
import be.ipl.abeille.domaine.Const.Tuile;
import be.ipl.abeille.domaine.Grille;
import be.ipl.abeille.domaine.Joueur;
import be.ipl.abeille.domaine.Partie;
import be.ipl.abeille.exceptions.TuileOccupeeException;

public class TestScore {
	@Test
	public void testGrilleVide() {
		Joueur j = new Joueur("Joueur", "mot_de_passe");
		Partie p = new Partie("La partie de test", new GregorianCalendar(),
				Difficulte.FACILE, j);
		Grille g = new Grille(j, p);

		Assert.assertEquals(g.calculerScore(), 0);
	}

	@Test
	public void testGrilleAvecUneTuileEnPositionZero() {
		Joueur j = new Joueur("Joueur", "mot_de_passe");
		Partie p = new Partie("La partie de test", new GregorianCalendar(),
				Difficulte.FACILE, j);
		Grille g = new Grille(j, p);

		try {
			g.placerTuile(0, Tuile.t1);
		} catch (TuileOccupeeException e) {
			Assert.assertFalse(true);
		}

		Assert.assertEquals(g.calculerScore(), p.getDifficulte().getPoint(1));
	}

	@Test
	public void testGrilleAvecUneTuileEnPositionAleatoire() {
		Joueur j = new Joueur("Joueur", "mot_de_passe");
		Partie p = new Partie("La partie de test", new GregorianCalendar(),
				Difficulte.FACILE, j);
		Grille g = new Grille(j, p);

		int position = (int) (Math.ceil(Math.random() * 20)) - 1;
		try {
			g.placerTuile(position, Tuile.t1);
		} catch (TuileOccupeeException e) {
			Assert.assertFalse(true);
		}

		Assert.assertEquals(g.calculerScore(), p.getDifficulte().getPoint(1));
	}

	@Test
	public void testGrilleAvecDeuxTuilesAdjacentes() {
		Joueur j = new Joueur("Joueur", "mot_de_passe");
		Partie p = new Partie("La partie de test", new GregorianCalendar(),
				Difficulte.FACILE, j);
		Grille g = new Grille(j, p);

		try {
			g.placerTuile(0, Tuile.t1);
			g.placerTuile(1, Tuile.t2);
		} catch (TuileOccupeeException e) {
			Assert.assertFalse(true);
		}

		Assert.assertEquals(g.calculerScore(), p.getDifficulte().getPoint(2));
	}

	@Test
	public void testGrilleAvecTroisTuilesAdjacentes() {
		Joueur j = new Joueur("Joueur", "mot_de_passe");
		Partie p = new Partie("La partie de test", new GregorianCalendar(),
				Difficulte.FACILE, j);
		Grille g = new Grille(j, p);

		try {
			g.placerTuile(0, Tuile.t1);
			g.placerTuile(1, Tuile.t2);
			g.placerTuile(2, Tuile.t3);
		} catch (TuileOccupeeException e) {
			Assert.assertFalse(true);
		}

		Assert.assertEquals(g.calculerScore(), p.getDifficulte().getPoint(3));
	}

	@Test
	public void testGrilleAvecNTuilesAdjacentes() {
		Joueur j = new Joueur("Joueur", "mot_de_passe");
		Partie p = new Partie("La partie de test", new GregorianCalendar(),
				Difficulte.FACILE, j);
		Grille g = new Grille(j, p);

		try {
			for (int i = 0; i < 20; i++) {
				g.placerTuile(i, Tuile.values()[i]);
			}
		} catch (TuileOccupeeException e) {
			Assert.assertFalse(true);
		}

		Assert.assertEquals(g.calculerScore(), p.getDifficulte().getPoint(20));
	}

	@Test
	public void testGrilleAvecDesSeriesDeDeux() {
		Joueur j = new Joueur("Joueur", "mot_de_passe");
		Partie p = new Partie("La partie de test", new GregorianCalendar(),
				Difficulte.FACILE, j);
		Grille g = new Grille(j, p);

		try {
			g.placerTuile(0, Tuile.t29);
			g.placerTuile(1, Tuile.t30);
			g.placerTuile(2, Tuile.t27);
			g.placerTuile(3, Tuile.t28);
			g.placerTuile(4, Tuile.t25);
			g.placerTuile(5, Tuile.t26);
			g.placerTuile(6, Tuile.t23);
			g.placerTuile(7, Tuile.t24);
			g.placerTuile(8, Tuile.t21);
			g.placerTuile(9, Tuile.t22);
			g.placerTuile(10, Tuile.t19a);
			g.placerTuile(11, Tuile.t20);
			g.placerTuile(12, Tuile.t17a);
			g.placerTuile(13, Tuile.t18a);
			g.placerTuile(14, Tuile.t15a);
			g.placerTuile(15, Tuile.t16a);
			g.placerTuile(16, Tuile.t13a);
			g.placerTuile(17, Tuile.t14a);
			g.placerTuile(18, Tuile.t11a);
			g.placerTuile(19, Tuile.t12a);
		} catch (TuileOccupeeException e) {
			Assert.assertFalse(true);
		}
		Assert.assertEquals(g.calculerScore(),
				p.getDifficulte().getPoint(2) * 10);
	}

	@Test
	public void testGrilleSeriesDeTroisAvecTrousEntreChacune() {
		Joueur j = new Joueur("Joueur", "mot_de_passe");
		Partie p = new Partie("La partie de test", new GregorianCalendar(),
				Difficulte.FACILE, j);
		Grille g = new Grille(j, p);

		try {
			g.placerTuile(0, Tuile.t1);
			g.placerTuile(1, Tuile.t2);
			g.placerTuile(2, Tuile.t3);

			g.placerTuile(4, Tuile.t1);
			g.placerTuile(5, Tuile.t2);
			g.placerTuile(6, Tuile.t3);

			g.placerTuile(8, Tuile.t1);
			g.placerTuile(9, Tuile.t2);
			g.placerTuile(10, Tuile.t3);

			g.placerTuile(12, Tuile.t1);
			g.placerTuile(13, Tuile.t2);
			g.placerTuile(14, Tuile.t3);

			g.placerTuile(16, Tuile.t1);
			g.placerTuile(17, Tuile.t2);
			g.placerTuile(18, Tuile.t3);
		} catch (TuileOccupeeException e) {
			Assert.assertFalse(true);
		}

		Assert.assertEquals(g.calculerScore(),
				p.getDifficulte().getPoint(3) * 5);
	}

	@Test
	public void testGrilleAvecJokerEnDebutDeSerie() {
		Joueur j = new Joueur("Joueur", "mot_de_passe");
		Partie p = new Partie("La partie de test", new GregorianCalendar(),
				Difficulte.FACILE, j);
		Grille g = new Grille(j, p);

		try {
			g.placerTuile(0, Tuile.joker);
			g.placerTuile(1, Tuile.t1);
			g.placerTuile(2, Tuile.t2);
		} catch (TuileOccupeeException e) {
			Assert.assertFalse(true);
		}

		Assert.assertEquals(g.calculerScore(), p.getDifficulte().getPoint(3));
	}

	@Test
	public void testGrilleAvecJokerEnFinDeSerie() {
		Joueur j = new Joueur("Joueur", "mot_de_passe");
		Partie p = new Partie("La partie de test", new GregorianCalendar(),
				Difficulte.FACILE, j);
		Grille g = new Grille(j, p);

		try {
			g.placerTuile(0, Tuile.t1);
			g.placerTuile(1, Tuile.t2);
			g.placerTuile(2, Tuile.joker);
		} catch (TuileOccupeeException e) {
			Assert.assertFalse(true);
		}

		Assert.assertEquals(g.calculerScore(), p.getDifficulte().getPoint(3));
	}

	@Test
	public void testGrilleAvecJokerHorsDUneSerieDevant() {
		Joueur j = new Joueur("Joueur", "mot_de_passe");
		Partie p = new Partie("La partie de test", new GregorianCalendar(),
				Difficulte.FACILE, j);
		Grille g = new Grille(j, p);

		try {
			g.placerTuile(0, Tuile.joker);
			g.placerTuile(2, Tuile.t1);
			g.placerTuile(3, Tuile.t2);
			g.placerTuile(4, Tuile.t3);
		} catch (TuileOccupeeException e) {
			Assert.assertFalse(true);
		}

		Assert.assertEquals(g.calculerScore(), p.getDifficulte().getPoint(3));
	}

	@Test
	public void testGrilleAvecJokerHorsDUneSerieDerriere() {
		Joueur j = new Joueur("Joueur", "mot_de_passe");
		Partie p = new Partie("La partie de test", new GregorianCalendar(),
				Difficulte.FACILE, j);
		Grille g = new Grille(j, p);

		try {
			g.placerTuile(0, Tuile.t1);
			g.placerTuile(1, Tuile.t2);
			g.placerTuile(2, Tuile.t3);
			g.placerTuile(4, Tuile.joker);
		} catch (TuileOccupeeException e) {
			Assert.assertFalse(true);
		}

		Assert.assertEquals(g.calculerScore(), p.getDifficulte().getPoint(3));
	}

	@Test
	public void testGrilleAvecJokerEntreDeuxSeriesDeTaillesDifferentesAndJokerDansPremiere() {
		Joueur j = new Joueur("Joueur", "mot_de_passe");
		Partie p = new Partie("La partie de test", new GregorianCalendar(),
				Difficulte.FACILE, j);
		Grille g = new Grille(j, p);

		try {
			g.placerTuile(0, Tuile.t1);
			g.placerTuile(1, Tuile.t2);
			g.placerTuile(2, Tuile.t3);
			g.placerTuile(3, Tuile.t4);
			g.placerTuile(4, Tuile.joker);
			g.placerTuile(5, Tuile.t2);
			g.placerTuile(6, Tuile.t3);
		} catch (TuileOccupeeException e) {
			Assert.assertFalse(true);
		}

		Assert.assertEquals(g.calculerScore(), p.getDifficulte().getPoint(5)
				+ p.getDifficulte().getPoint(2));
	}

	@Test
	public void testGrilleAvecJokerEntreDeuxSeriesDeTaillesDifferentesAndJokerDansSeconde() {
		Joueur j = new Joueur("Joueur", "mot_de_passe");
		Partie p = new Partie("La partie de test", new GregorianCalendar(),
				Difficulte.FACILE, j);
		Grille g = new Grille(j, p);

		try {
			g.placerTuile(0, Tuile.t1);
			g.placerTuile(1, Tuile.t2);
			g.placerTuile(2, Tuile.joker);
			g.placerTuile(3, Tuile.t2);
			g.placerTuile(4, Tuile.t3);
			g.placerTuile(5, Tuile.t4);
			g.placerTuile(6, Tuile.t5);
		} catch (TuileOccupeeException e) {
			Assert.assertFalse(true);
		}

		Assert.assertEquals(g.calculerScore(), p.getDifficulte().getPoint(5)
				+ p.getDifficulte().getPoint(2));
	}

	@Test
	public void testGrilleAvecJokerEntreDeuxSeriesDeTaillesIdentiques() {
		Joueur j = new Joueur("Joueur", "mot_de_passe");
		Partie p = new Partie("La partie de test", new GregorianCalendar(),
				Difficulte.FACILE, j);
		Grille g = new Grille(j, p);

		try {
			g.placerTuile(0, Tuile.t1);
			g.placerTuile(1, Tuile.t2);
			g.placerTuile(2, Tuile.joker);
			g.placerTuile(3, Tuile.t2);
			g.placerTuile(4, Tuile.t3);
		} catch (TuileOccupeeException e) {
			Assert.assertFalse(true);
		}

		Assert.assertEquals(g.calculerScore(), p.getDifficulte().getPoint(3)
				+ p.getDifficulte().getPoint(2));
	}
	
	@Test(priority= 9)
	public void testGrilleLongueSuite() {
		Joueur j = new Joueur("Joueur", "mot_de_passe");
		Partie p = new Partie("La partie de test", new GregorianCalendar(),
				Difficulte.FACILE, j);
		Grille g = new Grille(j, p);

		try {
			g.placerTuile(0, Tuile.t4);
			g.placerTuile(1, Tuile.t12a);
			g.placerTuile(2, Tuile.t20);
			g.placerTuile(3, Tuile.joker);
			g.placerTuile(4, Tuile.t13a);
			g.placerTuile(5, Tuile.t15a);
			g.placerTuile(6, Tuile.t14a);
			g.placerTuile(7, Tuile.t15b);
			g.placerTuile(8, Tuile.t16a);
			g.placerTuile(9, Tuile.t23);
			g.placerTuile(10, Tuile.t19a);
			g.placerTuile(11, Tuile.t27);
			g.placerTuile(12, Tuile.t5);
			g.placerTuile(13, Tuile.t8);
			g.placerTuile(14, Tuile.t11a);
			g.placerTuile(15, Tuile.t11b);
			g.placerTuile(16, Tuile.t25);
			g.placerTuile(17, Tuile.t2);
			g.placerTuile(18, Tuile.t6);
			g.placerTuile(19, Tuile.t18a);
		} catch (TuileOccupeeException e) {
			Assert.assertFalse(true);
		}
		int score = g.calculerScore();
		System.out.println(score);
		Assert.assertEquals(score,
				20);
	}
}
